import React from 'react';
import classnames from 'classnames';
import styles from './index.module.less';

/**
 * Typography 基础组件属性
 */
export interface TypographyProps {
  /** 自定义 CSS 类名 */
  className?: string;
  /** 自定义内联样式 */
  style?: React.CSSProperties;
  /** 子元素内容 */
  children?: React.ReactNode;
}

/**
 * 标题组件属性
 */
export interface TitleProps extends TypographyProps {
  /** 标题级别，对应 h1-h6 标签
   * @default 1
   */
  level?: 1 | 2 | 3 | 4 | 5 | 6;
  /** 文本类型，用于显示不同的颜色主题
   * - primary: 主要文本颜色，通常为品牌主色调（蓝色）
   * - secondary: 次要文本颜色，通常为较浅的灰色，用于辅助信息
   * - success: 成功状态颜色，通常为绿色，用于成功提示或状态
   * - warning: 警告状态颜色，通常为橙色/黄色，用于警告信息
   * - danger: 危险状态颜色，通常为红色，用于错误提示或危险操作
   */
  type?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger';
  /** 是否禁用状态，禁用时文本变灰且不可选中 */
  disabled?: boolean;
  /** 是否添加标记样式（黄色背景高亮） */
  mark?: boolean;
  /** 是否显示为代码样式（等宽字体，灰色背景） */
  code?: boolean;
  /** 是否显示为键盘按键样式（带边框和阴影） */
  keyboard?: boolean;
  /** 是否添加下划线 */
  underline?: boolean;
  /** 是否添加删除线 */
  delete?: boolean;
  /** 是否加粗显示 */
  strong?: boolean;
  /** 是否斜体显示 */
  italic?: boolean;
  /** 文本溢出省略配置
   * - true: 单行省略
   * - number: 多行省略，指定行数
   * - false: 不省略
   */
  ellipsis?: boolean | number;
}

/**
 * 文本组件属性
 */
export interface TextProps extends TypographyProps {
  /** 点击事件处理函数 */
  onClick?: (event: React.MouseEvent<HTMLSpanElement>) => void;
  /** 文本类型，用于显示不同的颜色主题
   * - primary: 主要文本颜色，通常为品牌主色调（蓝色）
   * - secondary: 次要文本颜色，通常为较浅的灰色，用于辅助信息
   * - success: 成功状态颜色，通常为绿色，用于成功提示或状态
   * - warning: 警告状态颜色，通常为橙色/黄色，用于警告信息
   * - danger: 危险状态颜色，通常为红色，用于错误提示或危险操作
   */
  type?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger';
  /** 字体大小，单位为 px
   * @default 14
   */
  size?: number;
  /** 是否显示为块级元素
   * @default false
   */
  block?: boolean;
  /** 是否禁用状态，禁用时文本变灰且不可选中 */
  disabled?: boolean;
  /** 是否添加标记样式（黄色背景高亮） */
  mark?: boolean;
  /** 是否显示为代码样式（等宽字体，灰色背景） */
  code?: boolean;
  /** 是否显示为键盘按键样式（带边框和阴影） */
  keyboard?: boolean;
  /** 是否添加下划线 */
  underline?: boolean;
  /** 是否添加删除线 */
  delete?: boolean;
  /** 是否加粗显示 */
  strong?: boolean;
  /** 是否斜体显示 */
  italic?: boolean;
  /** 文本溢出省略配置
   * - true: 单行省略
   * - number: 多行省略，指定行数
   * - false: 不省略
   */
  ellipsis?: boolean | number;
}

/**
 * 段落组件属性
 */
export interface ParagraphProps extends TypographyProps {
  /** 文本类型，用于显示不同的颜色主题
   * - primary: 主要文本颜色，通常为品牌主色调（蓝色）
   * - secondary: 次要文本颜色，通常为较浅的灰色，用于辅助信息
   * - success: 成功状态颜色，通常为绿色，用于成功提示或状态
   * - warning: 警告状态颜色，通常为橙色/黄色，用于警告信息
   * - danger: 危险状态颜色，通常为红色，用于错误提示或危险操作
   */
  type?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger';
  /** 是否禁用状态，禁用时文本变灰且不可选中 */
  disabled?: boolean;
  /** 是否添加标记样式（黄色背景高亮） */
  mark?: boolean;
  /** 是否显示为代码样式（等宽字体，灰色背景） */
  code?: boolean;
  /** 是否显示为键盘按键样式（带边框和阴影） */
  keyboard?: boolean;
  /** 是否添加下划线 */
  underline?: boolean;
  /** 是否添加删除线 */
  delete?: boolean;
  /** 是否加粗显示 */
  strong?: boolean;
  /** 是否斜体显示 */
  italic?: boolean;
  /** 文本溢出省略配置
   * - true: 单行省略
   * - number: 多行省略，指定行数
   * - false: 不省略
   */
  ellipsis?: boolean | number;
}

/**
 * 渲染装饰元素的辅助函数
 * @param children 子元素内容
 * @param props 装饰属性配置
 * @returns 包装后的 React 元素
 */
const renderWithDecorations = (
  children: React.ReactNode,
  props: {
    /** 是否添加标记样式（黄色背景高亮） */
    mark?: boolean;
    /** 是否显示为代码样式（等宽字体，灰色背景） */
    code?: boolean;
    /** 是否显示为键盘按键样式（带边框和阴影） */
    keyboard?: boolean;
    /** 是否加粗显示 */
    strong?: boolean;
    /** 是否斜体显示 */
    italic?: boolean;
    /** 是否添加删除线 */
    delete?: boolean;
    /** 是否添加下划线 */
    underline?: boolean;
  }
) => {
  let content = children;
  
  if (props.mark) content = <mark>{content}</mark>;
  if (props.code) content = <code>{content}</code>;
  if (props.keyboard) content = <kbd>{content}</kbd>;
  if (props.strong) content = <strong>{content}</strong>;
  if (props.italic) content = <em>{content}</em>;
  if (props.delete) content = <del>{content}</del>;
  if (props.underline) content = <u>{content}</u>;
  
  return content;
};

/**
 * Typography 基础组件
 * 提供统一的文本样式容器，支持嵌套使用
 */
const Typography: React.FC<TypographyProps> & {
  /** 标题组件，支持 h1-h6 级别 */
  Title: React.FC<TitleProps>;
  /** 文本组件，用于行内文本显示 */
  Text: React.FC<TextProps>;
  /** 段落组件，用于段落文本显示 */
  Paragraph: React.FC<ParagraphProps>;
} = ({ children, className, style }) => {
  return (
    <div className={classnames(styles.typography, className)} style={style}>
      {children}
    </div>
  );
};

/**
 * 标题组件
 * 支持 h1-h6 六个级别的标题，可配置多种文本样式和装饰效果
 */
const Title: React.FC<TitleProps> = ({
  level = 1,
  type,
  disabled,
  mark,
  code,
  keyboard,
  underline,
  delete: del,
  strong,
  italic,
  ellipsis,
  className,
  style,
  children,
}) => {
  const titleClass = classnames(
    styles.title,
    styles[`title-${level}`],
    type && styles[`type-${type}`],
    {
      [styles.disabled]: disabled,
      [styles.mark]: mark,
      [styles.code]: code,
      [styles.keyboard]: keyboard,
      [styles.underline]: underline,
      [styles.delete]: del,
      [styles.strong]: strong,
      [styles.italic]: italic,
      [styles.ellipsis]: ellipsis === true,
      [styles.ellipsisMultiple]: typeof ellipsis === 'number',
    },
    className
  );

  const titleStyle: React.CSSProperties = {
    ...(typeof ellipsis === 'number' && {
      WebkitLineClamp: ellipsis,
    }),
    ...style,
  };

  const content = renderWithDecorations(children, {
    mark,
    code,
    keyboard,
    strong,
    italic,
    delete: del,
    underline,
  });

  // 使用条件渲染替代动态标签
  switch (level) {
    case 1:
      return <h1 className={titleClass} style={titleStyle}>{content}</h1>;
    case 2:
      return <h2 className={titleClass} style={titleStyle}>{content}</h2>;
    case 3:
      return <h3 className={titleClass} style={titleStyle}>{content}</h3>;
    case 4:
      return <h4 className={titleClass} style={titleStyle}>{content}</h4>;
    case 5:
      return <h5 className={titleClass} style={titleStyle}>{content}</h5>;
    case 6:
      return <h6 className={titleClass} style={titleStyle}>{content}</h6>;
    default:
      return <h1 className={titleClass} style={titleStyle}>{content}</h1>;
  }
};

/**
 * 文本组件
 * 用于行内文本显示，支持多种文本样式和装饰效果
 */
const Text: React.FC<TextProps> = ({
  type,
  size = 14,
  block,
  disabled,
  mark,
  code,
  keyboard,
  underline,
  delete: del,
  strong,
  italic,
  ellipsis,
  className,
  style,
  onClick,
  children,
}) => {
  const textClass = classnames(
    styles.text,
    type && styles[`type-${type}`],
    {
      [styles.block]: block,
      [styles.disabled]: disabled,
      [styles.mark]: mark,
      [styles.code]: code,
      [styles.keyboard]: keyboard,
      [styles.underline]: underline,
      [styles.delete]: del,
      [styles.strong]: strong,
      [styles.italic]: italic,
      [styles.ellipsis]: ellipsis === true,
      [styles.ellipsisMultiple]: typeof ellipsis === 'number',
    },
    className
  );

  const textStyle: React.CSSProperties = {
    fontSize: `${size}px`,
    ...(typeof ellipsis === 'number' && {
      WebkitLineClamp: ellipsis,
    }),
    ...style,
  };

  const content = renderWithDecorations(children, {
    mark,
    code,
    keyboard,
    strong,
    italic,
    delete: del,
    underline,
  });

  return (
    <span className={textClass} style={textStyle} onClick={onClick}>
      {content}
    </span>
  );
};

/**
 * 段落组件
 * 用于段落文本显示，支持多种文本样式和装饰效果
 */
const Paragraph: React.FC<ParagraphProps> = ({
  type,
  disabled,
  mark,
  code,
  keyboard,
  underline,
  delete: del,
  strong,
  italic,
  ellipsis,
  className,
  style,
  children,
}) => {
  const paragraphClass = classnames(
    styles.paragraph,
    type && styles[`type-${type}`],
    {
      [styles.disabled]: disabled,
      [styles.mark]: mark,
      [styles.code]: code,
      [styles.keyboard]: keyboard,
      [styles.underline]: underline,
      [styles.delete]: del,
      [styles.strong]: strong,
      [styles.italic]: italic,
      [styles.ellipsis]: ellipsis === true,
      [styles.ellipsisMultiple]: typeof ellipsis === 'number',
    },
    className
  );

  const paragraphStyle: React.CSSProperties = {
    ...(typeof ellipsis === 'number' && {
      WebkitLineClamp: ellipsis,
    }),
    ...style,
  };

  const content = renderWithDecorations(children, {
    mark,
    code,
    keyboard,
    strong,
    italic,
    delete: del,
    underline,
  });

  return (
    <p className={paragraphClass} style={paragraphStyle}>
      {content}
    </p>
  );
};

// 组合导出
Typography.Title = Title;
Typography.Text = Text;
Typography.Paragraph = Paragraph;

export { Typography, Title, Text, Paragraph };
export default Typography;
